package jmine.tec.persist.schema.impl.parsers;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jmine.tec.persist.schema.api.SchemaElement;
import jmine.tec.persist.schema.api.SchemaElementParser;
import jmine.tec.persist.schema.impl.elements.Schema;

/**
 * Classe abstrata de schema element parsers.
 * 
 * @author lundberg
 * @param <S> elemento criado pelo parser
 */
public abstract class AbstractSchemaElementParser<S extends SchemaElement> implements SchemaElementParser<S> {

    private final Pattern pattern;
    
    private final Schema schema;

    /**
     * Construtor
     * 
     * @param pattern pattern dos statements reconhecidos por esse parser
     * @param schema o schema sobre o qual iremos atuar
     */
    public AbstractSchemaElementParser(Pattern pattern, Schema schema) {
        this.pattern = pattern;
        this.schema = schema;
    }

    /**
     * Construtor. A regex passada é compilada com a flag CASE_INSENSITIVE habilitada.
     * 
     * @param regex expressão regular que identifica statements reconhecidos por este parser
     * @param schema o schema sobre o qual iremos atuar
     */
    public AbstractSchemaElementParser(String regex, Schema schema) {
        this(Pattern.compile(regex, Pattern.CASE_INSENSITIVE), schema);
    }

    /**
     * {@inheritDoc}
     */
    public boolean matches(String statement) {
        return this.pattern.matcher(statement).matches();
    }

    /**
     * {@inheritDoc}
     */
    public S parse(String statement) {
        Matcher matcher = this.pattern.matcher(statement);
        if (!matcher.matches()) {
            throw new IllegalArgumentException();
        }
        return this.doParse(matcher);
    }

    /**
     * Efetua o parse efetivamente, obtendo as informações a partir dos grupos identificados pelo matcher.<br/>
     * O matcher já vem executado, basta consultá-lo.
     * 
     * @param matcher matcher
     * @return elemento resultante do parse
     */
    protected abstract S doParse(Matcher matcher);

    /**
     * @return the schema
     */
    public Schema getSchema() {
        return schema;
    }
}
